package com.wct.mall.aspectj;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 使用切面记录日志
 * @author WEI
 * @date 2020/3/24
 */
@Aspect
@Component
@Slf4j
public class LogAspect {

    /**
     * com.wct.mall.controller包下所有类所有方法
     */
    @Pointcut("execution(* com.wct.mall.controller.*.*(..))")
    public void controllerLog() {
    }

    @Before("controllerLog()")
    public void doControllerBefore(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        HttpServletRequest request = attributes.getRequest();
        String url = request.getRequestURI();
        String ip = request.getRemoteAddr();
        String classMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();

        RequestLog requestLog = new RequestLog(url, ip, classMethod, args);
        log.info("LogAspect Request Before : {}", requestLog);
    }

    @After("controllerLog()")
    public void doControllerAfter() {
//        log.info("LogAspect --------doAfter--------");
    }

    @AfterReturning(returning = "result", pointcut = "controllerLog()")
    public void doControllerAfterReturn(Object result) {
        log.info("LogAspect Request Return result: {}", result);
    }

    @Getter
    @Setter
    @ToString
    @AllArgsConstructor
    private static class RequestLog {
        private String url;
        private String ip;
        private String classMethod;
        private Object[] args;
    }

    @Pointcut("execution(* com.wct.mall.service.*.*(..))")
    public void serviceLog() {
    }

    @Before("controllerLog()")
    public void doServiceBefore(JoinPoint joinPoint) {
    }
    @After("controllerLog()")
    public void doServiceAfter() {
//        log.info("LogAspect --------doAfter--------");
    }

    @AfterReturning(returning = "result", pointcut = "controllerLog()")
    public void doServiceAfterReturn(Object result) {
//        log.info("Request Return result: {}", result);
    }
}
